import datetime  
import time
import numpy as np
from metric_class import PrometheusMetricClass
import logging
import requests
import json

# Prometheus 服务器地址  
prometheus_url = 'http://10.103.44.67:9090/api/v1/query_range'

# 企业微信机器人
target_url = 'http://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxxxxxxxxxxxxxxx' 

# 配置日志记录  
logging.basicConfig(  
    level=logging.INFO,  # 设置日志级别为 DEBUG  
    format='%(asctime)s - %(levelname)s - %(message)s',  # 日志格式  
    handlers=[  
        # logging.FileHandler('app.log'),  # 将日志输出到文件  
        logging.StreamHandler()  # 也输出到控制台  
    ]  
)  
# 效率测试
def timeit_decorator(func):  
    def wrapper(*args, **kwargs):  
        start_time = time.time()  
        result = func(*args, **kwargs)  
        end_time = time.time()  
        execution_time = end_time - start_time  
        print(f"Execution time of {func.__name__}: {execution_time} seconds")  
        return result  
    return wrapper

@timeit_decorator
def get_24_cpu_max():

    # PromQL 查询表达式  
    cpu_query = '100 - avg(irate(node_cpu_seconds_total{mode="idle"}[2m])) by (instance) * 100'  

    # 当前时间戳  
    end_time = int(time.time())  

    # 一天前的时间戳  
    start_time = end_time - 86400  # 86400 秒 = 1 天  

    # 查询参数  
    cpu_params = {  
        'query': cpu_query,  
        'start': start_time,  
        'end': end_time,  
        'step': 60  # 或者其他您想要的步长  
    }  

    prometheusobj = PrometheusMetricClass(prometheus_url)

    cpu_data = prometheusobj.metric_query(cpu_params)
 
    metric_dict = {}
    if cpu_data:  
        for cpu_data_one in cpu_data:
            # 转换值并找到最大值  
            max_value = None  
            max_timestamp = None 
            for timestamp, value in cpu_data_one['values']:  
                value_float = float(value)  # 转换字符串为浮点数  
                if max_value is None or value_float > max_value:  
                    max_value = value_float  
                    max_timestamp = timestamp

            max_readable_time = datetime.datetime.fromtimestamp(max_timestamp).strftime('%Y-%m-%d %H:%M:%S')
            metric_dict[cpu_data_one['metric']["instance"]] = [f"{max_value:.2f}", max_readable_time]
        
        # 输出最大值和其对应的时间戳  
        logging.info(f"CPU最大值: {metric_dict}") 
    else:
        logging.error("cpu最大值信息未找到")

    return metric_dict

def get_now_disk_info():

    # PromQL 查询表达式  
    disk_query = 'node_filesystem_free_bytes{fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|devtmpfs|fuse.*",mountpoint!~"/boot.*"} / node_filesystem_size_bytes{fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|devtmpfs|fuse.*",mountpoint!~"/boot.*"} * 100'  

    # 当前时间戳  
    end_time = int(time.time())  

    # 十分钟前的时间戳  
    start_time = end_time - 60  # 86400 秒 = 1 天  

    # 查询参数  
    disk_params = {  
        'query': disk_query,  
        'start': start_time,  
        'end': end_time,  
        'step': 60
    }  

    prometheusobj = PrometheusMetricClass(prometheus_url)

    disk_data = prometheusobj.metric_query(disk_params)
    if disk_data:
        metric_list = []
        for disk_data_one in disk_data:
            readable_time = datetime.datetime.fromtimestamp(disk_data_one['values'][0][0]).strftime('%Y-%m-%d %H:%M:%S')
            dict_val = float(disk_data_one['values'][0][1])
            metric_list.append([disk_data_one['metric']['instance'], disk_data_one['metric']["mountpoint"], f"{dict_val:.2f}", readable_time])
        
        logging.info(f"获取硬盘信息: {metric_list}")
    else:
        logging.error("获取硬盘信息失败")
    return metric_list

def get_now_memory_info():
    memory_query = '((node_memory_MemTotal_bytes - node_memory_MemFree_bytes - node_memory_Buffers_bytes - node_memory_Cached_bytes) / (node_memory_MemTotal_bytes )) * 100'

    # 当前时间戳  
    end_time = int(time.time())  

    # 十分钟前的时间戳  
    start_time = end_time - 60  # 86400 秒 = 1 天  

    # 查询参数  
    memory_params = {  
        'query': memory_query,  
        'start': start_time,  
        'end': end_time,  
        'step': 60
    }  

    prometheusobj = PrometheusMetricClass(prometheus_url)

    memory_data = prometheusobj.metric_query(memory_params)
    if memory_data:
        metric_list = []
        for memory_data_one in memory_data:
            readable_time = datetime.datetime.fromtimestamp(memory_data_one['values'][0][0]).strftime('%Y-%m-%d %H:%M:%S')
            memory_val = float(memory_data_one['values'][0][1])
            metric_list.append([memory_data_one['metric']['instance'], f"{memory_val:.2f}", readable_time])
        
        logging.info(f"获取内存信息: {metric_list}")
    else:
        logging.error("获取内存信息失败")

    return metric_list    

def get_now_ceph_info():
    ceph_query = 'ceph_cluster_total_used_bytes/ceph_cluster_total_bytes'  

    # 当前时间戳  
    end_time = int(time.time())  

    # 十分钟前的时间戳  
    start_time = end_time - 60  # 86400 秒 = 1 天  

    # 查询参数  
    ceph_params = {  
        'query': ceph_query,  
        'start': start_time,  
        'end': end_time,  
        'step': 60
    }  

    prometheusobj = PrometheusMetricClass(prometheus_url)

    ceph_data = prometheusobj.metric_query(ceph_params)
    if ceph_data:
        metric_list = []
        for ceph_data_one in ceph_data:
            readable_time = datetime.datetime.fromtimestamp(ceph_data_one['values'][0][0]).strftime('%Y-%m-%d %H:%M:%S')
            ceph_val = float(ceph_data_one['values'][0][1])
            metric_list.append([ceph_data_one['metric']['instance'], f"{ceph_val:.2f}", readable_time])
        
        logging.info(f"获取硬盘信息: {metric_list}")
    else:
        logging.error("获取硬盘信息失败")

    return metric_list  

ceph_info = get_now_ceph_info()
cpu_info = get_24_cpu_max()
disk_list = get_now_disk_info()
memory_list = get_now_memory_info()


ceph_segment = ""
for ceph_info_one in ceph_info:
    if float(ceph_info_one[1]) > 70:
        ceph_segment += f">当前分布存储负载:<font color=\"warning\">[{ceph_info_one[1]}%] ,运维请注意</font>\n"
    else:
        ceph_segment += f">当前分布存储负载:<font color=\"info\">[{ceph_info_one[1]}%]</font>\n"

cpu_segment = ""
for node_name, node_val in cpu_info.items():
    if float(node_val[0]) > 80:
        cpu_segment += f">昨日最高CPU:<font color=\"warning\">【{node_name}】:{node_val[0]}% [{node_val[1]}],运维请注意</font>\n"
    else:
        cpu_segment += f">昨日最高CPU:<font color=\"info\">【{node_name}】:[{node_val[0]}%] [{node_val[1]}]</font>\n"

disk_segment = ""
for disk_list_one in disk_list:
    if float(disk_list_one[2]) > 80:
        disk_segment += f">当前硬盘负载:<font color=\"warning\">【{disk_list_one[0]}】:[{disk_list_one[1]}] [{disk_list_one[2]}%] [{disk_list_one[3]}],运维请注意</font>\n"
    else:
        disk_segment += f">当前硬盘负载:<font color=\"info\">【{disk_list_one[0]}】:[{disk_list_one[1]}] [{disk_list_one[2]}%] [{disk_list_one[3]}]</font>\n"

memory_segment = ""
for memory_list_one in memory_list:
    if float(memory_list_one[1]) > 90:
        memory_segment += f">当前内存负载:<font color=\"warning\">【{memory_list_one[0]}】:[{memory_list_one[1]}%] [{memory_list_one[2]}] ,运维请注意</font>\n"
    else:
        memory_segment += f">当前内存负载:<font color=\"info\">【{memory_list_one[0]}】:[{memory_list_one[1]}%] [{memory_list_one[2]}] </font>\n"

for one_segment in [cpu_segment, disk_segment, memory_segment, ceph_segment]:
    temp_data = {
        "msgtype": "markdown",
        "markdown": {
            "content": f"""✉【 运维每日巡检 】✉ \n
            {one_segment}"""
        }
    }

    data = json.dumps(temp_data)
    # 发起转发请求
    header = {
        "Content-Type": "application/json",
        "Charset": "UTF-8"
        }
    response = requests.post(url=target_url, data=data, headers=header)

    # 返回转发请求的响应内容
    logging.info("机器人消息发送：%s" %response.json())